═══ 1. RexxBase The dBase Database For Rexx ═══ RexxBase and "The dBase Database for Rexx" are trademarks of American Coders, LTD. OS/2 is a registered trademark of the International Business Machines Corporation. dBase, dBase III and dBase IV are trademarks of Borland Corporation. Other trademarks are the trademarks of their respective trademark owners. Contacts: American Coders, LTD. Post Office Box 97462 Raleigh, NC 27624 (919) 846-2014 CompuServe ID: 74150,2370 Internet(USENET) ID: joe@usacoder.rtp.nc.us Spring 1997 Edition. Version 2.21. Copyright 1993-97 American Coders LTD Raleigh NC USA ═══ 1.1. Rights and Limitations ═══ American Coders, LTD makes no warranties as to the information in this guide. Additionally, American Coders Ltd is not responsible or liable for any loss or damage of any kind resulting from use of this product. The Software is protected by the Copyright laws of the United States of America, as well as by the Copyright laws of many other countries pursuant to international treaties. All rights reserved. No part of the RexxBase computer program, documentation or related files may be reproduced photocopied, stored on a retrieval system, or transmitted except as provided by U. S. Copyright law. ═══ 1.2. System Overview. ═══ RexxBase is a REXX external function DLL to be used by your command files to access dBase files. RexxBase offers database access functions to Rexx command procedures. By using the RexxBase functions, Rexx programs gain access to tens of thousands of database files written, primarily, for the PC/MS Dos environment. RexxBase generates dBase field names and values that are available directly to a Rexx program. The Rexx program can change this data and update dBase files directly. Also database file control information is available to the Rexx program. This information includes such data as last date the database was updated, number of records on file, field names, etc. ═══ 1.3. Version and Requirements. ═══ Version 2.21. RexxBase runs under o OS/2 2.x or higher and Warp o requires a minimum of 6 megabytes of RAM. o requires 500k of disk space. ═══ 1.4. Version History. ═══ The following is a basic history of changes for each version and release. ═══ 1.4.1. Version 2.21 Apr 30, 1997 ═══ Documentation update. Removed references to Assocication of Shareware Professionals and UUNET access. CreateIndex and AddTagToMDX ignored the RexxBase.Unique value. Memo Field wiped out during update if the field is preceded by a date field ═══ 1.4.2. Version 2.20 Sept 30, 1996 ═══ MDX Tag file logic control improved. Added new Control variable RexxBase.IncludeCentury. If it is set to YES then all date logic and routines require century to be used in date fields. Corrected date calculation logic. ScanForRecord (rv) failed to set file positioning parameters when BOF was reached. SummarizeDBF correction. GotoRecord function failed with MDX files. Added ADDON.EXT file for VisPro REXX users. ═══ 1.4.3. Version 2.11 May 1, 1996 ═══ Unique logic corrected, duplicate keys were added to indexes even with unique switch set to true. Simplified and improved export/import functions. Current key not set correctly. Broke update logic. Improved indexing logic for tags. Packing logic improved. ═══ 1.4.4. Version 2.10 March 21, 1996 ═══ Added new function to registered DLL. RexxBase_WriteDBFWithLock. This will allow serialization of database writes and prevent errors when multiple hits occur to the same database file and associated index and text files. Added database variable "databasename".dbasefileformat. This returns dBase3 or dBase4, based on the dbf's format. Note: without MDX files or MEMO fields a DBF file format defaults to dBase3. Added internal record locking to registered version (rv) through the use of semaphores. Added database variable "databasename".dbasefileformat. This returns dBase3 or dBase4, based on the dbf's format. Note: without MDX files or MEMO fields a DBF file format defaults to dBase3. Recompiled INSTALL.EXE and REXXBASE.EXE with newest version of VisPro/REXX. (3.01). DLL program would allow for only 3 MDX tags. EXE program could not create indexes with numeric fields. Modify function was using the current file's dBaseFileFormat field instead of the global field. Thereby, preventing conversions of files from one format to another. Documentation failed to fully describe the RexxBase.ERROR control variable. Corrected documentation with regards to specifying a TAG name when opening a file. Writes followed immediately by an Update would not create valid indexes and caused SYS3175 errors. Corrected EXE errors when catalog file contained a DBF that doesn't exist. Corrected problem when adding an MDX tag in the EXE. The tag name would not show up. PackDBF function didn't update the header correctly. ═══ 1.4.5. Version 2.06 January 22, 1996 ═══ Install program was marked as not executable. ═══ 1.4.6. Version 2.05 January 2, 1996 ═══ Install program now looks for config.sys in BOOTed drive. If unable to allocate memory in OPEN function was causing a 3175 error. Enhanced record scope. Added logic to allow binary data to be stored in CHAR and MEMO fields. RexxBase.UseStringLengths = "YES|NO" Corrected ModifyDBF function causing a 3175 error. Added code to registered version to prevent copyright notice from being displayed. Improved Export/Import function handling of signed numeric data. ═══ 1.4.7. Version 2.04 Sept 30, 1995 ═══ ReadPrevDBF and others failed when GOTORecord(bottom) was used. UpdateDBF failed for both NDX and MDX indexes. Packing dBase IV style DBT files used incorrect blocking factor. This could and most likely did create exception conditions. Packing dBase IV MDX files got larger in size. Reset Index Logic failed to verify if any TAGs were in use. ═══ 1.4.8. Version 2.03 July 31, 1995 ═══ The switch AllowDuplicateIndexes now works in conjunction with the index file indicator Duplicates Allowed. MDX indexing algorithm improved and corrected. NDX file links updated incorrectly for large files. SummarizeDBF function corrupted field that was before a numeric field. Added VX-Rexx macro facility. INSTALL program was not HPFS aware. ═══ 1.4.9. Version 2.02 June 15, 1995 ═══ Corrected documentation error. RexxBase.SkipDeleted switches use ON or OFF. Corrected DLL to reflect documentation: RexxBase.dBaseFileType should be RexxBase.dBaseFileFormat. Use RexxBase.dBaseFileFormat. Corrected DLL to reflect documentation: RexxBase.dBaseFileType default value is "dbase3". Improved GotoRecord function. Specifically TOP parameter and indexes now in synch. CREATE and PACKING functions failed for dBase IV memo fields. Corrected documentation error. References to RexxBase.AllowDuplicateIndex corrected to RexxBase.AllowDuplicateIndexes. Corrected Reindex problem. Not building control blocks correctly. Function required closing DBF before using again. Patched Reindex function memory leak. CreateDBFFrom function required closing source DBF before using again. Restored CloseAllDBF to unregistered version. Filter routines recalculated dates twice to produce incorrect results(rv). REXXBASE.EXE concatenated INDEX filenames incorrectly. ═══ 1.4.10. Version 2.01 May 16, 1995 ═══ Shareware zip files missing component files for install process. ═══ 1.4.11. Version 2.00 May 15, 1995 ═══ Corrected bug with filtering routines. Corrected bug with duplicate indexes not being caught. Corrected bug in Rexxbase_DateCalc. Added function Rexxbase_DayOfWeek to registered version. ═══ 1.4.12. Version 2.00 BETA Apr. 15, 1995 ═══ Introduced dBase IV MDX files and the following new functions: o RexxBase_SetIndexTagName o RexxBase_CreateMultipleIndexFile o RexxBase_AddTagToIndex o RexxBase_DropTagFromIndex o RexxBase_LockRecord o RexxBase_FindAndLockRecord o RexxBase_GotoAndLockRecord Introduced several new control fields: o RexxBase.AllowDuplicateIndexes o Rexxbase.Logical o RexxBase.SkipDeleted o RexxBase.dBaseFileType Introduced several new database control variables: o dbfname.IndexCount o dbfname.IndexFilename o dbfname.IndexFileType.xxx o dbfname.IndexFields.xxx o dbfname.IndexTagname.xxx.yyy o dbfname.IndexTagFields.xxx.yyy o dbfname.IndexValue.xxx(.yyy) Corrected several bugs and documentation errors. Bug in subroutine db3_create_index failed to generate valid anchor block. Documentation failed to inform that the filter string of the RexxBase_FilterDBF and RexxBase_ScanForRecord must be enclosed in quotes. ═══ 1.5. American Coders Ltd. ═══ American Coders, LTD. Post Office Box 97462 Raleigh, NC 27624 (919) 846-2014 CompuServe ID: 74150,2370 Programming Solutions For Your Business ═══ 1.6. How To Install ═══ Use the INSTALL.EXE that came with this program The install program allows you to specify if you want your CONFIG.SYS file updated. If you chose this you will be prompted for a backup filename. You can specify if you want all the files moved to the target directory. Copy the RXBASCAT.DBF and RXBASCAT.MDX files to the target directory. Have the RexxBase Front-End program copied to the desktop. RexxBase is distributed using the shareware system. Every shareware copy of the program comes with a 30 day trial offer. If after 30 days the user finds the RexxBase product acceptable they are expected to register and pay $95.00 plus shipping/handling/taxes. Registered users of the product receive a free upgrade to the current release, 90 days free support on CompuServe and 30 days free telephone support. ═══ 1.7. What Registering Gets You. ═══ When you register you receive: o The registered user DLL. o Limited rights to distribute the DLL. o Upgrade to the next release and immediate bug fixes. o Hardcopy documentation. o One months telephone and e-mail support. ═══ 1.8. How To Register Your Copy ═══ We have several methods for you to register your copy of RexxBase. o Registration Form. o PsL - Public Software Library - 800/Fax/WWW Credit Card Orders. o BMT - BMT Micro - 800/Fax/WWW Credit Card Orders o Immediate BBS Download - with Credit Card. o CompuServe SWREG. There is also a shipping and handling charge. For U.S. and Canada registrations it is $5.00. For all other international orders $10.00. If you are planning to order ten (10) or more copies use the SITELICE.DOC in your package. ═══ 1.8.1. Registration Form. ═══ Print out the file REGISTER.FRM. Attach a check and mail to us using the address on the form (or see above). ═══ 1.8.2. PsL - Public Software Library - 800/Fax/WWW Credit Card Orders. ═══ American Coders is using the services of PsL "Public (software) Library". They provide a service for all shareware authors, for a small fee, paid by the author, they will take credit card orders through their 800 number and Fax. Once PsL has notified us of your order, we will ship it within two days. PsL does NOT handle question or inquiries. RexxBase Psl item/product number is 11174. CREDIT CARD ORDERS ONLY - You can order with MC, Visa, AMEX, or Discover from Public (software) Library by calling 800-2424-PsL or 713-524-6394 or by FAX to 713-524-6398 or by CIS Email to 71355,470. You can also mail credit card orders to PsL at P.O.Box 35705, Houston, TX 77235-5705. THE ABOVE NUMBERS ARE FOR ORDERS ONLY. Any questions about the status of the shipment of the order, refunds, registration options, product details, technical support, volume discounts, dealer pricing, site licenses, etc., must be directed to 919-846-2014 or write American Coders at our address. To insure that you get the latest version, PsL will notify you the day of your order and we will ship the product directly to you. ═══ 1.8.3. BMT - BMT Micro - 800/Fax/WWW Credit Card Orders ═══ American Coders is using the services of BMT Micro. They provide a service for all shareware authors, for a small fee, paid by the author, they will take credit card orders through their BBS, Internet Web site, 800 number and Fax. Once BMT has notified us of your order, we will ship it within two days. BMT Micro PO Box 15016 Wilmington, NC 28408 U.S.A. Voice Orders: 8am - 7pm EST (-5 GMT) (800) 414-4268 (orders only) (910) 791-7052 Fax Orders: (910) 350-2937 24 hours / 7 Days (800) 672-1672 24 hours / 7 Days Online Orders via modem (910) 350-8061 10 lines, all 14.4K (910) 799-0923 Direct 28.8K line Ordering and general ordering questions: Via AOL bmtmicro Via MSN bmtmicro Via Prodigy HNGP66D Via Compuserve 74031,307 via Internet orders@bmtmicro.com telnet@bmtmicro.com http://www.wilmington.net/bmtmicro BMT accepts Visa, Mastercard, Discover, American Express, Money Order, Cashiers Check, Personal Check. Please do not send cash in the mail. Personal checks are subject to clearance. ═══ 1.8.4. Another Credit Card Method And Faster Too. ═══ Peter Norloff's OS2SHAREWARE Bulletin Board will allow you to register. OS2SHAREWARE accepts MC/Visa orders. Once the order has been placed you immediately receive your copy of the register package. While this copy may be the fully registered version, you'll want to let us know you are out there. Inside the package there is a I AM REGISTERED form. Fill it out and mail to us. This will guarantee you receive the free upgrade you're due. Call (In VA. USA) 1-703-385-4325. Follow the directions from the main menu for registering shareware. ═══ 1.8.5. CompuServe SWREG. ═══ CompuServe offers a service to register shareware software. GO SWREG and follow the directions. RexxBase SWREG number is 1953. Charges are billed to your CompuServe account. Any questions about the status of the shipment of the order, refunds, registration options, product details, technical support, volume discounts, dealer pricing, site licenses, etc, must be directed to 919-846-2014 or write American Coders at our address. ═══ 2. RexxBase File Structures. ═══ Every attempt has been made to keep the RexxBase DBF, DBT, MDX and NDX files similar. But due to the inherent differences between DOS, OS2, REXX and PRG files we could not make the fully functional features of a MDX or NDX file similar. For example, no dBase functions are allowed in index definitions. ═══ 2.1. File Naming. ═══ RexxBase does not assume default file extensions. This due to the inherent nature of HPFS files with its flexible file names. When opening and creating files be sure to use the DBF, NDX and MDX suffix. Since memo files are never defined, DBT files are the exception to this rule. ═══ 2.2. Database (DBF) File. ═══ There should be no difference between RexxBase DBF files and other xBase DBF. If you feel that you found an inconsistency with RexxBase DBF files, please notify us immediately. ═══ 2.3. Memo (DBT) File. ═══ There two different formats for DBT files. Both are dependent on which file type was used when the DBF file is created. DBT files used to store MEMO field data, look like regular variables to Rexx. With our testing, we have stored fields up to 262144 bytes in length. The theoretical limit is 2^32-1. This may incompatible with other xBase products. Please refer to the Memo and binary data storage sections for more information. ═══ 2.3.1. Memo (DBT) File for dBase III format. ═══ dBase III files use a less dynamic storage algorithm. These files tend to get rather large if the DBF file is not packed often. DBT files used to store MEMO field data. With our testing, we have stored fields up to 262144 bytes in length. The theoretical limit is 2^32-1. This may incompatible with other xBase products. Please refer to the Memo and binary data storage sections for more information. ═══ 2.3.2. Memo (DBT) File for dBase IV format. ═══ dBase IV files use a garbage collection algorithm to reuse space from formerly used memo disk space. The algorithm is a LRU. While the files won't grow as rapidly as dBase III DBTs. It's still a good idea to pack the associated DBF. ═══ 2.4. Index (NDX) File Field Differences. ═══ The ability to use index files is an integral part of any good database system. We have introduced, what we feel, is an improved, yet limited, features to index files in RexxBase. ┌──────────┬─────────────────────────────────────────────┐ │Difference│Description │ ├──────────┼─────────────────────────────────────────────┤ │Simple │RexxBase does not use xBase functions within │ │Data Types│index functions. Nor does it use inverse │ │ │definitions, i.e. using a minus sign to move │ │ │in a reverse key scan. │ ├──────────┼─────────────────────────────────────────────┤ │Mixing │RexxBase allows the mixing of Character, │ │Data Types│Numeric and Date data types. All data in │ │ │this format are treated as Character by │ │ │RexxBase. │ ├──────────┼─────────────────────────────────────────────┤ │Date Data │Date data types are treated as Character data│ │Types │and stored in the index in the native format.│ │ │Date data types can be concatenated together │ │ │with other data types. Some xBase products │ │ │store date in the index in a floating point │ │ │format. By removing the floating point │ │ │format you should see a improvement in index │ │ │file accessing for data types. │ ├──────────┼─────────────────────────────────────────────┤ │Numeric │Numeric data types are stored in a floating │ │Data Types│point format. When a key is defined as │ │ │numeric all of the fields are summed │ │ │together. │ ├──────────┼─────────────────────────────────────────────┤ │Accessing │The only time you may access NDX files from │ │xBase NDX │other xBase programs is if the dBase index │ │files. │file is strictly Character or Numeric fields │ │ │ONLY. Indexes using xBase functions are not │ │ │supported by RexxBase. │ └──────────┴─────────────────────────────────────────────┘ See also Rexxbase.Unique. See also Rexxbase.AllowDuplicateIndexes. ═══ 2.5. Multiple Index (MDX) File Field Differences. ═══ The ability to use index files is an integral part of any good database system. We have introduced, what we feel, is an improved, yet limited, features to index file in RexxBase. ┌──────────┬─────────────────────────────────────────────┐ │Difference│Description │ ├──────────┼─────────────────────────────────────────────┤ │Simple │RexxBase does not use xBase functions within │ │Data Types│index functions. Nor does it use inverse │ │ │definitions, i.e. using a minus sign to move│ │ │in a reverse key scan. │ ├──────────┼─────────────────────────────────────────────┤ │Mixing │RexxBase allows the mixing of Character, │ │Data Types│Numeric and Date data types. All data in │ │ │this format are treated as Character by │ │ │RexxBase. │ ├──────────┼─────────────────────────────────────────────┤ │Date Data │Date data types are treated as Character data│ │Types │and stored in the index in the native format.│ │ │Date data types can be concatenated together │ │ │with other data types. Some xBase products │ │ │store date in the index in a floating point │ │ │format. By removing the floating point │ │ │format you should see a improvement in index │ │ │file accessing for data types. │ ├──────────┼─────────────────────────────────────────────┤ │Numeric │Numeric data types are stored in a floating │ │Data Types│point format. When a key is defined as │ │ │numeric all of the fields are summed │ │ │together. │ ├──────────┼─────────────────────────────────────────────┤ │Accessing │The only time you may access MDX files from │ │xBase MDX │other xBase programs is if the dBase index │ │files. │file is strictly Character or Numeric fields │ │ │ONLY. Indexes using xBase functions are not │ │ │supported by RexxBase. │ ├──────────┼─────────────────────────────────────────────┤ │FOR │The FOR logical filter is not supported. │ │filters. │ │ ├──────────┼─────────────────────────────────────────────┤ │Descending│Descending indexes are not supported. │ │Indexes │ │ └──────────┴─────────────────────────────────────────────┘ See also Rexxbase.Unique. See also Rexxbase.AllowDuplicateIndexes. ═══ 3. How Initialize REXX For RexxBase Functions. ═══ Before calling any RexxBase functions your REXX command file must register the RexxBase DLL. To do this use the REXX command RXFUNCADD. You need to register only one RexxBase function - Rexxbase_Init. Rexxbase_Init, when called, will register all of the other RexxBase routines. Since Rexxbase_Init cannot register itself, your Rexx program must register it. Use RXFUNCADD to register the Rexxbase_Init function. Once registered, RexxBase will not have to be registered until the next time you restart OS/2. If you want your REXX program can register the RexxBase functions. The format of the command is RXFUNCADD(FUNCTION, DLL, PROCEDURE) FUNCTION is the name of the RexxBase routine as your procedure will call it. DLL is the name of the RexxBase DLL file. (Unless you rename it, it will always be REXXBASE). PROCEDURE is the name of the function internal to the RexxBase DLL. Your program should contain the following: /* REXX */ ret = rxfuncadd(rexxbase_init,Rexxbase,"Rexxbase_Init") ret = rexxbase_init() ═══ 3.1. Example of Dropping a RexxBase Function. ═══ When your procedure is done with the RexxBase functions it can drop the RexxBase functions. This may help reduce memory requirements and free up system resources. Once dropped, a function will have to be reregistered if it is to be used again. rxfuncdrop(rexxbase_opendbf,Rexxbase,"Rexxbase_OpenDBF") Return codes most likely to be returned are: o 0 - OK. o 40 - function not found. For more information about return codes from Rexx, refer to the IBM documentation. ═══ 4. The RexxBase Functions. ═══ This release of RexxBase offers several functions to read, write and update your database records. Also available are functions to create database, modify database structures and to sort databases. ═══ 4.1. General Database Processing Functions. ═══ The following are considered general functions. These functions allow you to open, read, write, update, move within, and close database files. ═══ 4.1.1. Rexxbase_OpenDBF. ═══ Description. Prior to processing a database file, the file must be opened. When your procedure opens the database file several activities occur. o The database file is opened. o RexxBase creates database related stem variable concerning system and file status. o RexxBase creates a stem variable containing field names, types and sizes. o If indexes are specified then these files are opened. Purpose. To open the database for processing. Format. rexxbase_opendbf('dbfname'[,'TAG=tagfieldname'index1|[,index2[,..]]]) Parameters. dbfname The REXX variable contains the name of your database as it is known to the operating system. TAG='tagfieldname' If the DBF has an associated MDX file you can open the DBF and specify which TAG to be used as an index. Due to the interpretive nature of REXX, place this option in quotes. Otherwise REXX will interpret it as a logical statement and replace with either 1(TRUE) or 0(FALSE). THIS IS AN OPTIONAL PARAMETER AND MUST BE SPECIFIED IMMEDIATELY AFTER THE DBF OPTION. index1 The master index file name as it is known to the operating system. Unlike the dbfname, which is the REXX variable name passed within quotes. The index file name is the OS/2 filename. You can use a REXX variable to pass the name, just don't put it in quotes. THIS IS AN OPTIONAL PARAMETER. index2 .. The alternative index file names as they are known to the operating system. Like the master index file name, they are the OS/2 filenames. You can use a REXX variable to pass the name, just don't put it in quotes. THIS IS AN OPTIONAL PARAMETER. You must set the database name in the variable prior to use. And you must pass the variable name in a string. For example. myfilename = 'c:\xbase\machines.dbf' ret = rexxbase_opendbf('myfilename') Return Value Description ''. Normal No REXX DBF Name Specified The first parameter of function call is missing. Bad Variable Name The variable name passed to the routine is not valid No File Name Assigned To Variable. The variable was not assigned a value. Database Name Already In Use. The name passed is already assigned to another opened database. Can't Open. Operating System error. File and system errors are written to the console, printer or rexxbase.error stem variable. Missing Index Filename, Database Is Open. The MDX file switch is set in the database control block, but the associated MDX file can not be found. Can't Open Index, Database File Opened. The RexxBase could not open any one of the index files specified. Depending on which file failed, any index files specified after it will not be opened. Database Tied To A Join The database is already in use by the RexxBase_JoinDBF function. (See registered user functions.) Missing Index Tag Name, Database is open. Tag was used as second parameter but no tag field name was found. No Index Tag File Opened, Database is open. The DBF does not have an associated MDX file. Tag Index File Has No Tags, Database is open. The MDX file has no tags defined Index Tag Name Not Found, Database is open. The tag field name used in the second parameter was not found in the tag field list of the MDX. For multi-user access refer to the following RexxBase variable: o Rexxbase.Read o Rexxbase.Write o Rexxbase.Share Sample Without An Index File /* REXX */ dbf = 'c:\users\net.dbf' ret = rexxbase_opendbf('dbf') if ret \= '' then do say ret exit end Sample With An Index File /* REXX */ dbf = 'c:\users\net.dbf' ret = rexxbase_opendbf('dbf','c:\users\net.ndx') if ret \= '' then do say ret exit end Sample With A TAG /* REXX */ dbf = 'c:\users\net.dbf' ret = rexxbase_opendbf('dbf','TAG=NETNAME') if ret \= '' then do say ret exit end ═══ 4.1.2. Rexxbase_CloseDBF. ═══ Description. When your procedure is done using the database file it should be closed. This allows your program to update the file correctly. Purpose. To close the database. Format. rexxbase_closedbf('dbfname') Parameters. dbfname The REXX variable contains the name of your database as you defined it in the Rexxbase_OpenDBF function. The name of the database is defined in a REXX variable. You must pass the variable name in a string. For example. myfilename = 'c:\xbase\machines.dbf' ret = rexxbase_closedbf('myfilename') Return Value Description ''. Normal No REXX DBF name Specified The first parameter of function call is missing. Unknown Database Name. The name found, in the passed parameter, is not the same used to open a database. Database Tied To A Join The database is already in use by the RexxBase_JoinDBF function. (See registered user functions.) Sample. /* REXX */ dbf = 'c:\users\net.dbf' ret = rexxbase_opendbf('dbf') if ret \= '' then do say ret exit end ret = rexxbase_closedbf('dbf') if ret \= '' then do say ret exit end say the number of dbf record(s) are dbf.recordcount Trick. Since the REXX environment is an integral part of the operating system and persistent nature of the REXX variable pool, you will run into trouble if you inadvertently leave a database open. One trick to get around this problem is to close the DBF before you open it. If you ignore the return code from RexxBase your program will continue to operate as normal. ═══ 4.1.3. Rexxbase_CloseAllDBF. ═══ Description. When your procedure is done using all of the database files they should be closed. This allows your program to update the files correctly. Purpose. To close all opened databases. Format. rexxbase_closealldbf() Parameters. N/A N/A The function does not use any parameters. For example, rexxbase_closealldbf() Return Value Description ''. Normal Even though there are no other return values. The internal processing errors may be found in the rexxbase.error stem variable. Sample. /* REXX */ dbf = 'c:\users\net.dbf' ret = rexxbase_opendbf('dbf') if ret \= '' then do say ret exit end dbf2 = 'c:\users\addr.dbf' ret = rexxbase_opendbf('dbf2',addr.ndx) if ret \= '' then do say ret exit end ret = rexxbase_closealldbf) if ret \='' then do say ret exit end ═══ 4.1.4. Rexxbase_ReadDBF. ═══ Description. Read the database fields into the REXX variables. This commands reads the next record in the file. Purpose. To read the next sequential record in the database. If the database was opened with an index, then the next record in the index list is read. Format. rexxbase_readdbf('dbfname') Parameters. dbfname The REXX variable contains the name of your database as you defined it in the Rexxbase_OpenDBF function. This function can avoid reading deleted records by setting Rexxbase.SkipDeleted. The name of the database is defined in a REXX variable. You must pass the variable name in a string. For example. /* REXX */ myfilename = 'c:\xbase\machines.dbf' rexxbase_readdbf('myfilename') Return Value Description ''. Normal No REXX DBF Name Specified The first parameter of function call is missing. BOF. End of file condition. No record is read. Record field values remain unchanged. Unknown Database Name. The name found in the passed parameter is not the same used to open the database. Internal File Processing Error. Record area could not be read. Find the XX error code in the rexxbase.error stem variable. Where XX is a return code from OS/2. If XX is equal to 5 then the operating system is denying access to that area. If XX is equal to 33 then the record area has been locked. For other values you can type on the command line 'HELP XX' to find the values for XX. Record Locked The file has been locked by another process. Database Tied To A Join The database is already in use by the RexxBase_JoinDBF function. (See registered user functions.) Sample. /* REXX */ dbf = 'c:\users\net.dbf' ret = rexxbase_opendbf('dbf') if ret \= '' then do say ret exit end ret = rexxbase_readdbf('dbf') if ret = BOF then do say end of file reached end ═══ 4.1.5. Rexxbase_ReadPrevDBF. ═══ Description. Read the database fields into the REXX variables. This commands reads the previous record in the file. Purpose. To read the previous sequential record in the database. If the database was opened with an index, then the previous record in the index list is read. Format. rexxbase_readprevdbf('dbfname') Parameters. dbfname The REXX variable contains the name of your database as you defined it in the Rexxbase_OpenDBF function. This function can avoid reading deleted records by setting Rexxbase.SkipDeleted. The name of the database is defined in a REXX variable. You must pass the variable name in a string. For example. myfilename = 'c:\xbase\machines.dbf' rexxbase_readprevdbf('myfilename') Return Value Description ''. Normal No REXX DBF Name Specified The first parameter of function call is missing. Unknown Database Name. The name found in the passed parameter is not the same used to open the database. Internal File Processing Error Record area could not be read. Find the XX error code in the rexxbase.error stem variable. Where XX is a return code from OS/2. If XX is equal to 5 then the operating system is denying access to that area. If XX is equal to 33 then the record area has been locked. For other values you can type on the command line 'HELP XX' to find the values for XX. TOF. Top of file condition. No record is read. Record field values remain unchanged. Record Locked The file has been locked by another process. Database Tied To A Join The database is already in use by the RexxBase_JoinDBF function. (See registered user functions.) Sample. /* Read the 10th and 9th records*/ dbf = 'c:\users\net.dbf' ret = rexxbase_opendbf('dbf') if ret \= '' then do say ret exit end ret = rexxbase_gotorecord('dbf',10) ret = rexxbase_readprevdbf('dbf') ret = rexxbase_closedbf('dbf') Trick. If you must have reverse indexes, open the database with the intended index, go to the BOTTOM of the database and readprev until TOF. ═══ 4.1.6. Rexxbase_GoToRecord. ═══ Description. The command will position at a specified record and read it. Purpose. To read a particular record in the database. Format. rexxbase_gotorecord('dbfname',recordnumber) Parameters. dbfname The REXX variable contains the name of your database as you defined it in the Rexxbase_OpenDBF function. recordnumber The record number to read, or the following words TOP - to go to the top of the database. BOT or BOTTOM - to go to the bottom of the database. This function can avoid reading deleted records by setting Rexxbase.SkipDeleted. The name of the database is defined in a REXX variable. You must pass the variable name in a string. For example. myfilename = 'c:\xbase\machines.dbf' rexxbase_gotorecord('myfilename',1) Return Value Description ''. Normal No REXX DBF Name Specified The first parameter of function call is missing. No Record Number Specified. You did not pass a record number in the second argument. Unknown Database Name. The name found in the passed parameter is not the same used to open the database. Bad Record Number. You passed a record number that is invalid or is less than one. No record is read. BOF. You passed a record number that is greater than the number on the file or used the BOT or BOTTOM option. No record is read. Record field values remain unchanged. BOF is a good return code if you used the BOT or BOTTOM option. TOF. You used the TOP option in the record number field. This is a good return code. Record Locked The file has been locked by another process. Database Tied To A Join The database is already in use by the RexxBase_JoinDBF function. (See registered user functions.) Sample. /* REXX */ /* assume the database has a field name AMOUNT. */ /* this example will get the last AMOUNT on file*/ dbf = 'c:\users\net.dbf' ret = rexxbase_opendbf('dbf') if ret \= '' then do say ret exit end ret = rexxbase_gotorecord('dbf',dbf.recordcount) if ret = '' then say dbf.amount ret = rexxbase_closedbf('dbf') ═══ 4.1.7. Rexxbase_WriteDBF. ═══ Description. This will add a new record to the end of the database. Purpose. To add records to the database. Format. rexxbase_writedbf('dbfname') Parameters. dbfname The REXX variable contains the name of your database as you defined it in the Rexxbase_OpenDBF function. The name of the database is defined in a REXX variable. You must pass the variable name in a string. For example. /* */ myfilename = 'c:\xbase\machines.dbf' ret = rexxbase_opendbf('myfilename') rexxbase_writedbf('myfilename') ret = rexxbase_closedbf('myfilename') Return Value Description ''. Normal No REXX DBF Name Specified The first parameter of function call is missing. Unknown Database Name. The name found in the passed parameter is not the same used to open the database. Record With Duplicate Key Not Written The control variable RexxBase.AllowDuplicatesIndexes has been set to NO. A matching index has been found. Therefore, the record was written to the DBF file. Remember, deleted records do not have their index entries removed until the database has been packed. Also, do not confuse this with the control variable RexxBase.Unique, which allows all records to be written to the database but prevents a duplicate index entry from being created. See Rexxbase.AllowDuplicateIndexes. Database Tied To A Join The database is already in use by the RexxBase_JoinDBF function. (See registered user functions.) Sample. /* REXX */ /* this example copies the first record of the database to the end */ dbf = 'c:\users\net.dbf' ret = rexxbase_opendbf('dbf') if ret \= '' then do say ret exit end ret = rexxbase_readdbf('dbf') if ret \= '' then do say read failed with ret exit end ret = rexxbase_writedbf('dbf') if ret \ = '' then do say write failed with ret exit end ret = rexxbase_closedbf('dbf') if ret \ = '' then do say close failed with ret exit end ═══ 4.1.8. Rexxbase_UpdateDBF. ═══ Description. This function will rewrite data at the current record position. Purpose. To update a record. Format. rexxbase_updatedbf('dbfname') Parameters. dbfname The REXX variable contains the name of your database as you defined it in the Rexxbase_OpenDBF function. The name of the database is defined in a REXX variable. You must pass the variable name in a string. For example. myfilename = 'c:\xbase\machines.dbf' ret = rexxbase_updatedbf('myfilename') Return Value Description ''. Normal No REXX DBF Name Specified The first parameter of function call is missing. Unknown Database Name. The name found in the passed parameter is not the same used to open the database. Invalid Record Position The current record pointer is either at TOF or BOF. It is not pointing to any particular record. Record With Duplicate Key Not Updated The control variable RexxBase.AllowDuplicatesIndexes has been set to NO. A matching index has been found. Therefore, the record was written to the DBF file. Remember, deleted records do not have their index entries removed until the database has been packed. Also, do not confuse this with the control variable RexxBase.Unique, which allows all records to be written to the database but prevents a duplicate index entry from being created. See Rexxbase.AllowDuplicateIndexes. Database Tied To A Join The database is already in use by the RexxBase_JoinDBF function. (See registered user functions.) Sample. /* REXX */ /* this example update the field AMOUNT on the first record of the database*/ dbf = 'c:\users\net.dbf' ret = rexxbase_opendbf('dbf') if ret \= '' then do say ret exit end ret = rexxbase_readdbf('dbf') if ret \= '' then do say read failed with ret exit end dbf.AMOUNT = dbf.AMOUNT * 2 ret = rexxbase_updatedbf('dbf') if ret \ = '' then do say update failed with ret exit end ret = rexxbase_closedbf('dbf') if ret \ = '' then do say close failed with ret exit end ═══ 4.2. Create and Modify Database Functions. ═══ The following functions allow you to create new or modify existing databases. ═══ 4.2.1. Rexxbase_CreateDBF ═══ Description. This will create a new database file. If the file is created with the RexxBase.dBaseFileFormat set to 'dbase4' a MDX file is created. Prior to calling the RexxBase Create function you must specify the fields and the characteristics for each field. You do this by creating field names using the database variable name concatenated with the FIELD string. ┌──────────┬───────────────┬───────────────┬───────────────┬──────────┐ │Database │*.FIELDCOUNT │The number of │ │ │ │Field │ │fields to be │ │ │ │Count │ │used for │ │ │ │ │ │creating the │ │ │ │ │ │database. │ │ │ ├──────────┼───────────────┼───────────────┼───────────────┼──────────┤ │Field Name│*.FIELDNAME.1 │The first field│Any valid dBase│ │ │1 │ │name. │field name. │ │ ├──────────┼───────────────┼───────────────┼───────────────┼──────────┤ │*.'field │The first field│Specify C for │ │ │ │name │type │character, L │ │ │ │1'.TYPE │ │for Logical, M │ │ │ │ │ │for Memo, N for│ │ │ │ │ │Numeric and D │ │ │ │ │ │for date. Any │ │ │ │ │ │other value │ │ │ │ │ │will cause the │ │ │ │ │ │create function│ │ │ │ │ │to fail. │ │ │ ├──────────┼───────────────┼───────────────┼───────────────┼──────────┤ │*.'field │The first field│Specify the │ │ │ │name │size or length.│field length. │ │ │ │1'.LENGTH │ │For Logical, │ │ │ │ │ │Memo and Date │ │ │ │ │ │field the size │ │ │ │ │ │field is │ │ │ │ │ │ignored and │ │ │ │ │ │RexxBase uses │ │ │ │ │ │the default │ │ │ │ │ │values. For │ │ │ │ │ │Character │ │ │ │ │ │fields specify │ │ │ │ │ │a value from 1 │ │ │ │ │ │to 254. For │ │ │ │ │ │Numeric fields │ │ │ │ │ │specify the │ │ │ │ │ │length in the │ │ │ │ │ │format of │ │ │ │ │ │length.decimal,│ │ │ │ │ │where length is│ │ │ │ │ │a value from 1 │ │ │ │ │ │to 19 and │ │ │ │ │ │decimal (no of │ │ │ │ │ │decimal │ │ │ │ │ │positions) is 0│ │ │ │ │ │to 9 (one less │ │ │ │ │ │than the │ │ │ │ │ │length). │ │ │ │ │ │Numeric │ │ │ │ │ │accuracy is │ │ │ │ │ │valid to 15 │ │ │ │ │ │integer digits │ │ │ │ │ │and 9 decimal │ │ │ │ │ │places. │ │ │ ├──────────┼───────────────┼───────────────┼───────────────┼──────────┤ │. │. │ │ │ │ ├──────────┼───────────────┼───────────────┼───────────────┼──────────┤ │Field n │*.FIELDNAME.n │The last field │ │ │ │ │ │in the │ │ │ │ │ │database. The │ │ │ │ │ │value of n │ │ │ │ │ │should be equal│ │ │ │ │ │to the value │ │ │ │ │ │specified in │ │ │ │ │ │dbname.FIELDCOU│ │ │ └──────────┴───────────────┴───────────────┴───────────────┴──────────┘ Purpose. To create a database. Format. rexxbase_createdbf('dbfname') Parameters. dbfname The REXX variable contains the name of the database similar in function to the database field in the Rexxbase_OpenDBF function. The name of the database is defined in a REXX variable. You must pass the variable name in a string. For example. myfilename = 'c:\xbase\newmachn.dbf' rexxbase_createdbf('myfilename') Return Value Description ''. Normal No REXX DBF Name Specified The first parameter of function call is missing. Bad Variable Name Variable used to pass database name is not a valid REXX variable name. No Filename Assigned To Variable. Variable used to pass database name is empty or unassigned. Database name Already In Use. Database name passed is already in use. Create Failed refer to the following: Unknown Field Type Use C, D, L, M, and N only for field types. Invalid field size For character fields use a size from 1 through 249. For numeric fields use a size of specification of xx.yy where xx is a value from 1 to 19 and yy is from 0 to 9 and yy is one less than xx. All other field type length specifications default to: 8 for D, 1 for L and 10 for M. Too many fields. Only 128 fields are allowed per database. Record size too large Records sizes are limited to 4000 bytes. To prevent unwanted destruction of a database file refer to the RexxBase variable Rexxbase.Safety Sample. /* REXX */ dbf.fieldcount = 4 dbf.fieldname.1 = location dbf.location.type = 'c' dbf.location.length = '10' dbf.fieldname.2 = inuse dbf.inuse.type = 'l' dbf.fieldname.3 = startuse dbf.startuse.type = 'd' dbf.fieldname.4 = prchcost dbf.prchcost.type = 'n' dbf.prchcost.length = '9.2' dbf = 'invntry.dbf' ret = rexxbase_createdbf('dbf') ═══ 4.2.2. Rexxbase_CreateFromDBF ═══ Description. This will create a new database file structure only. No data is added to the file. No structure modifications may be made. Purpose. To create a database structure. Format. rexxbase_createfromdbf('dbfname','newdbfname') Parameters. dbfname The REXX variable contains the name of the database similar in function to the database field in the Rexxbase_OpenDBF function. newdbfname The REXX variable contains the name of the new database. The name of the database is defined in a REXX variable. You must pass the variable name in a string. For example. oldfilename = 'c:\xbase\machn.dbf' newfilename ='c:\xbase\newmachn.dbf' rexxbase_createfromdbf('oldfilename','newfilename') Return Value Description ''. Normal No REXX DBF Name Specified The first parameter of function call is missing. Unknown Database Name. The name found in the passed parameter is not the same used to open the database. No DBF Name To Copy Structure To This functions expects a second parameter which contains the name of the file to be created. Bad Variable Name Variable used to pass database name is not a valid REXX variable name. No Filename Assigned To Variable. Variable used to pass database name is empty or unassigned. Database Name Already In Use. Database name passed is already in use. CreateFrom Failed Refer to the rexxbase.error stem variable.: To prevent unwanted destruction of a database file refer to the RexxBase variable Rexxbase.Safety Sample. /* REXX */ parse arg olddbf newdbf ret = rexxbase_opendbf('olddbf') ret = rexxbase_createfromdbf('olddbf','newdbf') ═══ 4.2.3. Rexxbase_ModifyDBF ═══ Description. This will modify the structure of a database file that is currently open. When a database is opened the database fields descriptions are loaded into REXX Variables. By changing the values in these REXX variables you can alter the characteristics of a database field, remove a database field and add new database fields. ┌──────────┬───────────────┬───────────────┬───────────────┐ │Database │*.FIELDCOUNT │The number of │ │ │Field │ │fields in the │ │ │Count │ │database. │ │ │ │ │Increase the │ │ │ │ │count of this │ │ │ │ │field when │ │ │ │ │adding new │ │ │ │ │records. If │ │ │ │ │you decrease │ │ │ │ │the count, the │ │ │ │ │trailing fields│ │ │ │ │will be │ │ │ │ │removed. To │ │ │ │ │remove fields │ │ │ │ │in the │ │ │ │ │beginning and │ │ │ │ │the middle of │ │ │ │ │the field │ │ │ │ │change the │ │ │ │ │field type 'P'.│ │ ├──────────┼───────────────┼───────────────┼───────────────┤ │Field Name│*.FIELDNAME.1 │The first field│ │ │1 │ │name. │ │ ├──────────┼───────────────┼───────────────┼───────────────┤ │*.'field │The first field│Specify C for │ │ │name │type. │character, L │ │ │1'.TYPE │ │for Logical, M │ │ │ │ │for Memo, N for│ │ │ │ │Numeric and D │ │ │ │ │for date. │ │ ├──────────┼───────────────┼───────────────┼───────────────┤ │*.'field │The first field│Specify the │ │ │name │size or length.│field length. │ │ │1'.LENGTH │ │For Logical, │ │ │ │ │Memo and Date │ │ │ │ │field the size │ │ │ │ │field is │ │ │ │ │ignored and │ │ │ │ │RexxBase uses │ │ │ │ │the default │ │ │ │ │values. For │ │ │ │ │Character │ │ │ │ │fields specify │ │ │ │ │a value from 1 │ │ │ │ │to 254. For │ │ │ │ │Numeric fields │ │ │ │ │specify the │ │ │ │ │length in the │ │ │ │ │format of │ │ │ │ │length.decimal,│ │ │ │ │where length is│ │ │ │ │a value from 1 │ │ │ │ │to 19 and │ │ │ │ │decimal (no of │ │ │ │ │decimal │ │ │ │ │positions) is 0│ │ │ │ │to 9 (one less │ │ │ │ │than the │ │ │ │ │length). │ │ │ │ │Numeric │ │ │ │ │accuracy is │ │ │ │ │valid to 15 │ │ │ │ │integer digits │ │ │ │ │and 9 decimal │ │ │ │ │places. │ │ ├──────────┼───────────────┼───────────────┼───────────────┤ │. │. │ │ │ ├──────────┼───────────────┼───────────────┼───────────────┤ │Field n │*.FIELDNAME.n │The last field │ │ │ │ │in the │ │ │ │ │database. The │ │ │ │ │value of n │ │ │ │ │should be equal│ │ │ │ │to the value │ │ │ │ │specified in │ │ │ │ │dbname.FIELDCOU│ │ └──────────┴───────────────┴───────────────┴───────────────┘ Purpose. To modify a database. Format. rexxbase_modifydbf('dbfname') Parameters. dbfname The REXX variable contains the name of the database similar in function to the database field in the Rexxbase_OpenDBF function. The name of the database is defined in a REXX variable. You must pass the variable name in a string. For example. myfilename = 'c:\xbase\machn.dbf' rexxbase_modifydbf('myfilename') Return Value Description ''. Normal No REXX DBF Name Specified The first parameter of function call is missing. Unknown Database Name. The name found in the passed parameter is not the same used to open the database. Modify Failed refer to the following: Unknown Field Type Use C, D, L, M, and N only for field types. Invalid field size For character fields use a size from 1 through 249. For numeric fields use a size of specification of xx.yy where xx is a value from 1 to 19 and yy is from 0 to 9 and yy is one less than xx. All other field type length specifications default to: 8 for D, 1 for L and 10 for M. Too many fields. Only 128 fields are allowed per database. Record size too large Records sizes are limited to 4000 bytes. Database Tied To A Join The database is already in use by the RexxBase_JoinDBF function. (See registered user functions.) Sample. /* REXX */ dbf = 'c:\xbase\newmachn.dbf' rexxbase_opendbf('dbf') dbf.fieldcount = 4 dbf.fieldname.1 = location dbf.location.type = 'c' dbf.location.length = '10' dbf.fieldname.2 = inuse dbf.inuse.type = 'l' dbf.fieldname.3 = startuse dbf.startuse.type = 'd' dbf.fieldname.4 = prchcost dbf.prchcost.type = 'n' dbf.prchcost.length = '9.2' ret = rexxbase_modifydbf('dbf') ═══ 4.3. Deleting and Packing Databases. ═══ The following function allow your REXX programs to logically delete, undelete and physically remove records from a database. ═══ 4.3.1. Rexxbase_DeleteRecord. ═══ Description. Marks the current record as deleted. Purpose. To logically delete a record. Format. rexxbase_deleterecord('dbfname') Parameters. dbfname The REXX variable contains the name of your database as you defined it in the Rexxbase_OpenDBF function. The name of the database is defined in a REXX variable. You must pass the variable name in a string. For example. ret = rexxbase_deleterecord('myfilename') Return Value Description ''. Normal No REXX DBF Name Specified The first parameter of function call is missing. Unknown Database Name. The name found in the passed parameter is not the same used to open the database. No Record Read. The procedure must do a record read before deleting a record. Database Tied To A Join The database is already in use by the RexxBase_JoinDBF function. (See registered user functions.) Sample. /* REXX */ /*mark the last record on file as undeleted */ dbf = 'c:\users\net.dbf' ret = rexxbase_opendbf('dbf') if ret \= '' then do say ret exit end ret = rexxbase_gotorecord('dbf',dbf.recordcount) if ret = '' then ret = rexxbase_deleterecord('dbf') ═══ 4.3.2. Rexxbase_UndeleteRecord. ═══ Description. Marks the current record as not deleted. Purpose. To logically undelete a record. Format. rexxbase_undeleterecord('dbfname') Parameters. dbfname The REXX variable contains the name of your database as you defined it in the Rexxbase_OpenDBF function. The name of the database is defined in a REXX variable. You must pass the variable name in a string. For example. rexxbase_undeleterecord('myfilename') Return Value Description ''. Normal No REXX DBF Name Specified The first parameter of function call is missing. Unknown Database Name. The name found in the passed parameter is not the same used to open the database. No Record Read. The procedure must do a record read before undeleting a record. Database Tied To A Join The database is already in use by the RexxBase_JoinDBF function. (See registered user functions.) Sample. /* REXX */ /*mark the last record on file as not deleted */ dbf = 'c:\users\net.dbf' ret = rexxbase_opendbf('dbf') if ret \= '' then do say ret exit end ret =rexxbase_gotorecord('dbf',dbf.recordcount) if ret = '' then ret = rexxbase_undeleterecord('dbf') ═══ 4.3.3. Rexxbase_PackDBF. ═══ Description. This function removes logically deleted records from the database. Purpose. To remove deleted records. If the file has been opened with indexes, then the index will be rebuilt. If the database has associated index files and they are not opened during the packing process the indexes will be incorrect. Format. rexxbase_packdbf('dbfname') Parameters. dbfname The REXX variable contains the name of your database as you defined it in the Rexxbase_OpenDBF function. The name of the database is defined in a REXX variable. You must pass the variable name in a string. For example. myfilename = 'c:\xbase\machines.dbf' ret = rexxbase_packdbf('myfilename') Return Value Description ''. Normal No REXX DBF Name Specified No argument was passed to the routine. Unknown Database Name. The name found in the passed parameter is not the same used to open the database. Database Tied To A Join The database is already in use by the RexxBase_JoinDBF function. (See registered user functions.) Record With Duplicate Key Not Updated The control variable RexxBase.AllowDuplicatesIndexes has been set to NO. A matching index has been found. Therefore, the record was written to the DBF file. Remember, deleted records do not have their index entries removed until the database has been packed. Also, do not confuse this with the control variable RexxBase.Unique, which allows all records to be written to the database but prevents a duplicate index entry from being created. See Rexxbase.AllowDuplicateIndexes. Sample. /* REXX */ dbf = 'c:\users\net.dbf' ret = rexxbase_opendbf('dbf') if ret \= '' then do say ret exit end ret = rexxbase_packdbf('dbf') ═══ 4.4. Index and Tag Functions ═══ The following functions allow you to access your database through indexes and to control the index files. ═══ 4.4.1. Rexxbase_FindRecord. ═══ Description. The command will position at a specified record using the master index file. Purpose. To read a particular record in the database using the index file. Format. rexxbase_findrecord('dbfname','string',[EXACT]) Parameters. dbfname The REXX variable contains the name of your database as you defined it in the Rexxbase_OpenDBF function. string The index key string used for searching. EXACT Optional indicator to tell RexxBase to find the exact 'string' in the index. This would cause a Hard Find. If not specified then RexxBase would execute a Soft Find. This function can avoid reading deleted records by setting Rexxbase.SkipDeleted. The name of the database is defined in a REXX variable. You must pass the variable name in a string. For example. myfilename = 'c:\xbase\machines.dbf' ret = rexxbase_findrecord('myfilename','LASER 11') Return Value Description ''. Normal No REXX DBF Name No argument was passed to the routine. No Locate String Specified Second parameter of function is missing. Unknown Database Name. The name found in the passed parameter is not the same used to open the database. Index File Not Opened Or Tag Set When the database was opened, no index files were specified and no TAG= parameter was specified. Record Not Found (when EXACT is specified) You passed a string that is not on the master index. No record is read. Record Not Found (when EXACT is not specified) The string entered is higher than any on the index. Internal File Processing Error. Record area could not be read. Find the XX error code in the rexxbase.error stem variable. Where XX is a return code from OS/2. If XX is equal to 5 then the operating system is denying access to that area. If XX is equal to 33 then the record area has been locked. For other values you can type on the command line 'HELP XX' to find the values for XX. Database Tied To A Join The database is already in use by the RexxBase_JoinDBF function. (See registered user functions.) Sample. /* REXX */ /* this example copies the finds a record on the database */ dbf = 'c:\users\net.dbf' ndx = 'c:\xbase\net.ndx' ret = rexxbase_opendbf('dbf',ndx) if ret \= '' then do say ret exit end ret = rexxbase_findrecord('dbf','USA001') if ret \= '' then do say find failed with ret exit end say Network Disposition For USA001 is dbf.dispo ret = rexxbase_closedbf('dbf') if ret \ = '' then do say close failed with ret exit end If you must have reverse indexes, open the database with the intended index, find the record to start at and readprev until TOF. ═══ 4.4.2. Rexxbase_SetIndexTagName. ═══ Description. The function provides an alternate method to specify which tag to use when finding records through a MDX files. Purpose. To specify which tag name to use in an MDX file. Format. rexxbase_setindextagname('dbfname','tagname') Parameters. dbfname The REXX variable contains the name of your database as you defined it in the Rexxbase_OpenDBF function. tagname The name of a known tag in the associated MDX file. The name of the database is defined in a REXX variable. You must pass the variable name in a string. For example. myfilename = 'c:\xbase\machines.dbf' ret = rexxbase_setindextagname('myfilename','location') Return Value Description ''. Normal No REXX DBF Name No argument was passed to the routine. No Index Tag Name Specified Second parameter of function is missing. Unknown Database Name. The name found in the passed parameter is not the same used to open the database. No Index Tag File Opened The database file does not have an associated MDX file. Primary Index Not MDX Type Your program has made the primary index file an NDX file. Tag Index File Has No Tags No tag has been assigned to the MDX file. Index Tag Name Not Found The tag name has not been defined in the MDX file. Sample. /* REXX */ /* this example copies the finds a record on the database */ dbf = 'c:\users\net.dbf' ret = rexxbase_opendbf('dbf') if ret \= '' then do say ret exit end ret = rexxbase_setindextagname('dbf','NETWORKS') if ret \= '' then do say find failed with ret exit end ret = rexxbase_findrecord('dbf','USA001') if ret \= '' then do say find failed with ret exit end say Network Disposition For USA001 is dbf.dispo ret = rexxbase_closedbf('dbf') if ret \ = '' then do say close failed with ret exit end ═══ 4.4.3. Rexxbase_CreateIndex ═══ Description. This will create an index for an currently open database. The call to the RexxBase Create Index function requires 3 parameters: Open Database Name, Index file name (FAT or HPFS format) and the string defining the index. RexxBase does not verify nor add the NDX file extension. It is recommended that your program specifies it. Purpose. To create an index for an open database. Format. rexxbase_createindex('dbfname',index file name,index string) Parameters. dbfname The REXX variable contains the name of the database similar in function to the database field in the Rexxbase_OpenDBF function. index file name Any valid file name in FAT or HPFS format. index string A string of characters used to specify the index. See REXXBASE.UNIQUE more information. See ndx definition more information. The name of the database is defined in a REXX variable. You must pass the variable name in a string. For example. myfilename = 'c:\xbase\newmachn.dbf' myindexname = 'c:\xbase\newmachn.ndx' rexxbase_opendbf('myfilename') rexxbase_createindex('myfilename',myindexname,'num+dept') Return Value Description ''. Normal No REXX DBF Name Specified No argument was passed to the routine. Unknown Database Name. The name found in the passed parameter is not the same used to open the database. No Index File Name Specified This procedure expects a second argument containing the new index file name. No Index Field Names Specified This procedure expects a third argument containing the index key. Index Not Built. A runtime error occurred. Review error message in rexxbase.error stem variable. Unknown Field Type Use C, D, L, M, and N only for field types. Invalid Index Size Indexes are limited to 100 bytes. Too Many Fields. Only 100 fields are allowed per index. Data Type Mismatch You can't mix numeric, character or date fields together Invalid Data Type Memo fields and logic fields are not allowed to be used as indexes. Database Tied To A Join The database is already in use by the RexxBase_JoinDBF function. (See registered user functions.) Sample. /* REXX */ dbf = 'c:\xbase\machn.dbf' ret = rexxbase_opendbf('dbf') ret = rexxbase_createindex('dbf','machn.ndx','machnum') ret = rexxbase_closedbf('dbf') ═══ 4.4.4. Rexxbase_CreateMultipleIndexFile ═══ Description. This will create a multiple index for a currently open database. The call to the RexxBase Create Multiple Index File function requires 2 parameters: Open Database Name and an index file name (FAT or HPFS format). RexxBase does not verify nor add the MDX file extension. It is recommended that your program specifies it. If the file was created with the RexxBase.dBaseFileType set to 'dbase4' a MDX file is created. This function does not create tags. To add an index tag use RexxBase_AddTagToIndex function. Purpose. To create a multiple index file for an open database. Format. rexxbase_createmultipleindexfile('dbfname',index file name) Parameters. dbfname The REXX variable contains the name of the database similar in function to the database field in the Rexxbase_OpenDBF function. index file name Any valid file name in FAT or HPFS format. See REXXBASE.UNIQUE more information. See MDX definition more information. The name of the database is defined in a REXX variable. You must pass the variable name in a string. For example. myfilename = 'c:\xbase\newmachn.dbf' myindexname = 'c:\xbase\newmachn.mdx' rexxbase_opendbf('myfilename') rexxbase_createmultipleindexfile('myfilename',myindexname) Return Value Description ''. Normal No REXX DBF Name Specified No argument was passed to the routine. Unknown Database Name. The name found in the passed parameter is not the same used to open the database. No Index File Name Specified This procedure expects a second argument containing the new index file name. Create Index File Failed. A runtime error occurred. Review error message in rexxbase.error stem variable. Database Tied To A Join The database is already in use by the RexxBase_JoinDBF function. (See registered user functions.) Sample. /* REXX */ dbf = 'c:\xbase\machn.dbf' ret = rexxbase_opendbf('dbf') ret = rexxbase_createmultipleindexfile('dbf','machn.mdx') ret = rexxbase_addtagtoindex('dbf','machnum') ret = rexxbase_closedbf('dbf') ═══ 4.4.5. Rexxbase_AddTagToIndex ═══ Description. This will add a tag index to a currently open database and MDX file. The call to the RexxBase Add Tag To Index function requires 3 parameters: Open Database Name, tag name and the string defining the index. Purpose. To create an index tag. Format. rexxbase_addtagtoindex('dbfname',index tag name,index string) Parameters. dbfname The REXX variable contains the name of the database similar in function to the database field in the Rexxbase_OpenDBF function. index tag name Any valid field name. Follow the field name conventions. index string A string of characters used to specify the index. See REXXBASE.UNIQUE more information. See MDX definition more information. The name of the database is defined in a REXX variable. You must pass the tag and variable name in a string. For example. myfilename = 'c:\xbase\newmachn.dbf' /* assumes there is an associated MDX file newmachn.mdx */ rexxbase_opendbf('myfilename') rexxbase_addtagtoindex('myfilename','Num_Dept','num+dept') Return Value Description ''. Normal No REXX DBF Name Specified No argument was passed to the routine. Unknown Database Name. The name found in the passed parameter is not the same used to open the database. No Tag Name Specified This procedure expects a second argument containing the new tag name. No Tag Index Field Specified This procedure expects a third argument containing the index key. Tag Index File Not Opened The DBF file does not have an associated MDX file that was opened when the DBF was opened. Failed To Add Tag To Index A runtime error occurred. Review error message in rexxbase.error stem variable. Unknown Field Type Use C, D, L, M, and N only for field types. Invalid Index Size Indexes are limited to 100 bytes. Too Many Fields. Only 100 fields are allowed per index. Data Type Mismatch You can't mix numeric, character or date fields together Invalid Data Type Memo fields and logic fields are not allowed to be used as indexes. Index Tag Name Too Long The second parameter is invalid. See above. Primary Index File Not MDX format. The primary index file must be the MDX file. Database Tied To A Join The database is already in use by the RexxBase_JoinDBF function. (See registered user functions.) Sample. /* REXX */ dbf = 'c:\xbase\machn.dbf' /* assume machn.mdx exists */ ret = rexxbase_opendbf('dbf') ret = rexxbase_addtagtoindex('dbf','machnum','machnum') ret = rexxbase_closedbf('dbf') ═══ 4.4.6. Rexxbase_DropTagFromIndex ═══ Description. This will remove a tag index from a currently open database and MDX file. The call to the RexxBase Drop Tag From Index function requires 2 parameters: Open Database Name and tag name. Purpose. To drop an index tag. Format. rexxbase_droptagfromindex('dbfname',index tag name) Parameters. dbfname The REXX variable contains the name of the database similar in function to the database field in the Rexxbase_OpenDBF function. index tag name An existing tag field name. The name of the database is defined in a REXX variable. You must pass the tag and variable name in a string. For example. myfilename = 'c:\xbase\newmachn.dbf' /* assumes there is an associated MDX file newmachn.mdx */ rexxbase_opendbf('myfilename') rexxbase_droptagfromindex('myfilename','Num_Dept') Return Value Description ''. Normal No REXX DBF Name Specified No argument was passed to the routine. Unknown Database Name. The name found in the passed parameter is not the same used to open the database. No Tag Name Specified The second argument contains the tag name to be dropped. Tag Index File Not Opened The DBF file does not have an associated MDX file that was opened when the DBF was opened. Primary Index File Not MDX format. The primary index file must be the MDX file. Database Tied To A Join The database is already in use by the RexxBase_JoinDBF function. (See registered user functions.) Failed To Drop Tag From Index A runtime error occurred. Review error message in rexxbase.error stem variable. Sample. /* REXX */ dbf = 'c:\xbase\machn.dbf' /* assume machn.mdx exists */ ret = rexxbase_opendbf('dbf') ret = rexxbase_droptagfromindex('dbf','machnum','machnum') ret = rexxbase_closedbf('dbf') ═══ 4.4.7. Rexxbase_ReindexDBF ═══ Purpose. To rebuild all open indexes for an open database. Format. ret = rexxbase_reindexdbf(dbfname) Parameters. dbfname The REXX variable contains the name of the database similar in function to the database field in the Rexxbase_OpenDBF function. Description. This will rebuild all the indexes that are opened for a database file. When a database has been changed without its associated indexes opened, the index pointers will be incorrect. This function will rebuild all indexes for the file. Also, use this function when many updates have been applied to a database, even with the index opened. This will maintain the indexes for efficiency. myfilename = 'c:\xbase\machn.dbf' myndxname = 'c:\xbase\machn.ndxf' rexxbase_reindexdbf('myfilename',myndxname) Return Value Description ''. Normal No REXX DBF Name Specified No argument was passed to the routine. Unknown Database Name. The name found in the passed parameter is not the same used to open the database. Database Tied To A Join The database is already in use by the RexxBase_JoinDBF function. (See registered user functions.) Sample. /* REXX */ dbf = 'c:\xbase\newmachn.dbf' rexxbase_opendbf('dbf','c:\xbase\newmachn.ndx') ret = rexxbase_reindexdbf('dbf') say newmachn.mdx has been rebuilt say newmachn.ndx has been rebuilt ret = rexxbase_closedbf('dbf') ═══ 4.5. Database Sorting. ═══ ═══ 4.5.1. Rexxbase_SortDBF ═══ Description. This will sort a database file by fields names and create a new database file. Prior to calling the RexxBase Sort function you must specify the sort fields and the sort order for each field. You do this by creating field names using the database variable name concatenated with the SORTFIELD string. ┌──────────┬───────────────┬───────────────┬───────────────┬──────────┐ │Sort Field│*.SORTFIELD.0 │The number of │ │ │ │Count │ │fields to be │ │ │ │ │ │used for sort │ │ │ │ │ │criteria. │ │ │ ├──────────┼───────────────┼───────────────┼───────────────┼──────────┤ │Sort Field│*.SORTFIELD.1 │The primary │*.SORTTYPE.1 │Use a │ │Name 1 │ │sort field. │ │value of │ │ │ │ │ │'-' (minus│ │ │ │ │ │sign) to │ │ │ │ │ │sort this │ │ │ │ │ │field in │ │ │ │ │ │descending│ │ │ │ │ │order. │ │ │ │ │ │Any other │ │ │ │ │ │value will│ │ │ │ │ │sort the │ │ │ │ │ │field in │ │ │ │ │ │ascending │ │ │ │ │ │order. │ ├──────────┼───────────────┼───────────────┼───────────────┼──────────┤ │. │. │ │ │ │ ├──────────┼───────────────┼───────────────┼───────────────┼──────────┤ │Sort Field│*.SORTFIELD.n │The last sort │ │ │ │n │ │field in │ │ │ │ │ │priority. The │ │ │ │ │ │value of n │ │ │ │ │ │should be equal│ │ │ │ │ │to the value │ │ │ │ │ │specified in │ │ │ │ │ │dbname.SORTFIEL│ │ │ └──────────┴───────────────┴───────────────┴───────────────┴──────────┘ Purpose. To sort a database. Format. rexxbase_sortdbf('dbfname',sortfilename) Parameters. dbfname The REXX variable contains the name of your database as you defined it in the Rexxbase_OpenDBF function. sortfilename The sorted output file name as it will be known to the operating system. This function can skip deleted records by setting Rexxbase.SkipDeleted. The name of the database is defined in a REXX variable. You must pass the variable name in a string. For example. myfilename = 'c:\xbase\machines.dbf' ret = rexxbase_sortdbf('myfilename','c:\xbase\machsort.dbf') Return Value Description ''. Normal No REXX DBF Name Specified The first parameter of function call is missing. No Sort DBF Name Specified The second parameter of function call is missing. Unknown Database Name. The name found in the passed parameter is not the same used to open the database. Sort Field Count Not Found The REXX variable containing the field count is missing. See *.SORTFIELD.0 above. Can't Find 'fieldname' The field name used by the SORTFIELD stem variables are not part of this database. Not Enough Memory For Summarizing or Sorting RexxBase uses the physical and virtual address space to perform the sort. The database to be sorted is too large for this process. Can't Open Sort DBF File. OS/2 returned a error code that indicates some type of error has occurred while opening the output database. Can't Write To Sort DBF File. OS/2 returned a error code that indicates some type of error has occurred while writing the output database. Unable To Write Fields To File. OS/2 returned a error code that indicates some type of error has occurred while writing the output database. Internal File Processing Area Record area could not be read. Find the XX error code in the rexxbase.error stem variable. Where XX is a return code from OS/2. If XX is equal to 5 then the operating system is denying access to that area. If XX is equal to 33 then the record area has been locked. For other values you can type on the command line 'HELP XX' to find the values for XX. Record Locked The file has been locked by another process. Sample. /* REXX */ /* sort on field name location (descending)*/ dbf = 'c:\users\net.dbf' ret = rexxbase_opendbf('dbf') if ret \= '' then do say ret exit end dbf.sortfield.0 = 1 dbf.sortfield.1 = location dbf.sorttype.1 = '-' ret = rexxbase_sortdbf('dbf','c:\users\sortloc.dbf') NOTE: MEMO fields for the original file are valid with the SORTED file. BUT these MEMO fields can be corrupted with either file changes or adds a MEMO field. THEREFORE, if you want to use the DBT (MEMO file) with the sorted file, you should copy the DBT file using the SORTED file name. dbf = 'presort.dbf' call rexxbase_opendbf 'dbf' call rexxbase_sortdbf 'dbf' 'sorted.dbf' 'COPY presort.dbt sorted.dbt' sdbf = 'sorted.dbf' call rexxbase_opendbf 'sdbf' ═══ 4.6. Registered User Functions. ═══ The following functions are available with the registered user package: o Rexxbase_ReadAndLockDBF o Rexxbase_ReadAndLockPrevDBF o Rexxbase_GoToAndLockRecord o Rexxbase_FindAndLockRecord o Rexxbase_WriteDBFWithLock o Rexxbase_LockDBF o Rexxbase_UnlockDBF o Rexxbase_SetLockTimeout o Rexxbase_ExportDBF o Rexxbase_ImportDBF o Rexxbase_FormatDate o Rexxbase_InternalDate o Rexxbase_DaysDifference o Rexxbase_DateCalc o Rexxbase_DayOfWeek o Rexxbase_FilterDBF o Rexxbase_ScanForRecord o Rexxbase_JoinDBF o Rexxbase_SummarizeDBF o Rexxbase_ChangePrimaryIndex o Rexxbase_Soundex ═══ 5. RexxBase Fields and Database Fields. ═══ RexxBase uses REXX Stem and Compound variables extensively to allow your procedure to use your database files. ═══ 5.1. RexxBase Fields. ═══ RexxBase PROVIDES several fields for controlling your database. All field names are associated with your database by using the stem variable name you pass to the RexxBase Functions. Also, RexxBase provides a stem variable for system errors. The field name is rexxbase.error . Refer to the section on error processing for more information and a list of potential error messages. Name Description. "database name".RECORDCOUNT Number of record on the file. Where database name is the name your program passes to RexxBase. "database name".DBASEFILEFORMAT A value of dBase3 or dBase4. The format of the DBF based on internal indicators. NOTE: without using MDX files or MEMO fields, the format defaults to dBase3. "database name".RECORDNUMBER The current record number. Where database name is the name your program passes to RexxBase. "database name".FILESTATUS TOF - Top of file, BOF - End of file, or null. "database name".RECORDSTATUS DELETED - current record is deleted, or null. "database name".LASTUPDATE Last day file was updated. "database name".FIELDCOUNT Number of fields on the database. database name".FIELDNAME.# Field names on the database. Where # is any number from 1 to the number of fields as specified in FIELDCOUNT. "database name"."fieldname".TYPE The database type for the respective field, see FIELDNAME.#. "fieldname" is the name of the field in the database. "database name"."fieldname".LENGTH The length of the respective field, see FIELDNAME.#. "fieldname" is the name of the field in the database. Numeric fields will have in the value in the format of xx.yy where xx is the length of the field and yy is the number of decimal positions. Memo fields are always 10. Logical fields are always 1. "database name".INDEXCOUNT Number of index files open for the database. "database name".INDEXFILETYPE.# Returns either NDX or MDX. Where # is any number from 1 to the number of fields as specified in INDEXCOUNT. "database name".INDEXFILENAME.# Operating System file names for the open index files. Where # is any number from 1 to the number of fields as specified in INDEXCOUNT. "database name".INDEXFIELDS.# Field names used for indexing. Where # is any number from 1 to the number of fields as specified in INDEXCOUNT. "database name".TAGFIELDS.#. For MDX index files, this is the number of defined TAG fields. Where # is any number from 1 to the number of fields as specified in INDEXCOUNT. "database name".INDEXTAGNAME.#.##. For MDX index files, this is the TAG field name. Where # is any number from 1 to the number of fields as specified in INDEXCOUNT. Where ## is any number from 1 to the number of fields as specified in INDEXFIELDS. "database name".INDEXTAGFIELDS.#.##. For MDX index files, these are the fields that are specified by the TAG name. Similar to INDEXFIELDNAME above. Where # is any number from 1 to the number of fields as specified in INDEXCOUNT. Where ## is any number from 1 to the number of fields as specified in INDEXFIELDS. "database name".INDEXVALUE.#(.##). This is the value for the current index record. Where # is any number from 1 to the number of fields as specified in INDEXCOUNT. For MDX TAG indexes, ## is any number from 1 to the number of fields as specified in INDEXFIELDS. ═══ 5.1.1. Field Naming Convention. ═══ With the exception of RexxBase database names, all database field names are prefixed by the Rexx variable you use to specify the database. For example if you used the REXX variable DNAME as the database name the field count variable name would be DNAME.FIELDCOUNT. Database field names are directly accessible by the field name in the database. For example if your database had three fields defined as NAME, CITY, ZIP, then your REXX procedure will be able to read from and write to these fields by using the name directly. The database name is not prefixed to the fields names. To find out the field names in a database use the following example: /* REXX */ parse arg dbfname do i = 1 to dbfname.fieldcount k = "say dbfname.fieldname.i " k = k || " dbfname."dbfname.fieldname.i".type" k = k || " dbfname."dbfname.fieldname.i".length" interpret k end /* do */ say dbfname do i = 1 to dbfname.recordcount say dbfname.recordstatus say reading is rexxbase_readdbf("dbfname") do j = 1 to dbfname.fieldcount k = "say dbfname.fieldname.j " k = k || " is dbfname." || dbfname.fieldname.j interpret k /* don't let the quoted field name fool you */ /* the first dbfname.fieldname.j will appear as the field name after interpretation*/ /* the second will have the value appear after interpretation */ end /* do */ end /* do */ /* since no index files */ if dbfname.indexcount = 0 then say "No MDX Files Or NDX files found" else do /* but there maybe a MDX file */ say "This file has an associated MDX file" end say rexxbase_closedbf("dbfname") return ═══ 5.1.2. Your Program Changing a RexxBase Field Value. ═══ In most cases if you change a RexxBase field value, like FIELDCOUNT there will be no effect internally to RexxBase or the actual database file. ═══ 5.2. Database Fields. ═══ Database field name are accessible by concatenating the database variable name, your procedure assigns when opening the database, with the field name in the database. For example if your database had three fields defined as NAME, CITY, ZIP, and your REXX procedure opened the database as ADDRESS then your REXX procedure will be able to read from and write to these fields by using the names ADDRESS.NAME, ADDRESS.CITY AND ADDRESS.ZIP. The database name is prefixed to the fields names. ═══ 5.2.1. Example of Field Naming. ═══ Unlike RexxBase field names, database field are never prefixed with the database name when used as a function parameter or in field definitions. For example when sorting on a field, you must specify what field to sort using the databasename.SORTFIELD.# construct. The field name you put into the assignment is simply the field name as defined to the dBase database. /* to sort on field ZIP in database ADDRESS */ address.sortfield.0 = 1 address.sortfield.1 = zip /* wrong */ /* address.sortfield.1 = address.zip */ /* this will assign the value of address.zip to address.sortfield.1 */ /* which will only work if the value of address.zip is zip */ ═══ 5.3. Field Verification. ═══ The following field verifications and edits are used. ═══ 5.3.1. Date Fields ═══ Dates are validated based on two parameters. First, is the RexxBase Variable RexxBase.FormatDate. Second, is the Country Code, as defined by OS/2 NLS. RexxBase.FormatDate takes precedence. If it is turned "OFF" then all date fields are assumed to be in the following 8 numeric-character format: CCYYMMDD. CC - century. YY - year. MM - month. DD - day. If you need to use dates that go past 1999/12/31 then you should always use this format. This is because the default century for the other formats is "1900." If RexxBase.FormatDate is "ON", the default value, then date fields are formatted based on the Country Code. As follows: (all are 8 bytes long with separators). MM/DD/YY, slashes or some other separator is required DD/MM/YY, slashes or some other separator is required YY/MM/DD, slashes or some other separator is required Edits are performed on all 4 types of date fields. Century is ignored and defaults to 19. Year is any numeric value from 00 to 99. Month is any numeric value from 01 to 12. Day is any numeric value from 01 to last day of month. ═══ 5.3.2. Numeric Fields ═══ Numeric field verification skips over white space characters until an alphanumeric character is found. If the first non-white space character is alphabetic then the value is stored as zero - NOTE: there is no error message. Field values larger than the defined length (and/or decimal count) are truncated. ═══ 5.3.3. Logical fields ═══ Logical fields are tested and verified for correctness as follows: ┌────────────────────┬───────┬──────────────────────────────┐ │First Byte of │Stored │ │ │Logical Field Value │As │ │ ├────────────────────┼───────┼──────────────────────────────┤ │T, t, 1, Y, or y │T │ │ ├────────────────────┼───────┼──────────────────────────────┤ │F, f, 0, N, or n │F │ │ ├────────────────────┼───────┼──────────────────────────────┤ │Any other value │F │Look for error message on │ │ │ │rexxbase.error stem variable.│ └────────────────────┴───────┴──────────────────────────────┘ RexxBase can also return REXX logical values. If the control variable REXXBASE.REXXLOGICALS is set to ON, then read functions will either return 0 for F value fields or 1 for T valued fields. ═══ 5.3.4. MEMO Fields. ═══ Memo field names follow the same field naming convention as other field names. ═══ 6. When You Are Done. ═══ After using the RexxBase functions your REXX command file may drop the RexxBase functions. This can be accomplished by using the Rexxbase_ShutDown function or issuing the Rexx command RXFUNCDROP for each function. While the IBM documentation recommends dropping functions. we feel that it is an unnecessary exercise. Do this only if you have literally thousands of functions registered. The space requirements are minimal, but the search time, for thousands of functions, may be significant. ═══ 6.1. Rexxbase_ShutDown. ═══ There may be a time when you want to drop all of the RexxBase functions from the Rexx function pool. To do this use the RexxBase command RexxBase_ShutDown. ShutDown function is to issue a Rexx Function Drop for each of the RexxBase functions. It is pretty much performs the opposite utility of the RexxBase_Init command. RexxBase_ShutDown() There are no parameters. There is no return code. ═══ 6.2. Dropping Individual RexxBase Functions. ═══ The format of the command is RXFUNCDROP(function) function is the name of the RexxBase routine as your procedure defined it. rxfuncdrop(rexxbase_opendbf) Return codes most likely to be returned are: o 0 - OK. o 40 - function not found. ═══ 7. Returned Values and Internal Errors. ═══ The following two sections are lists of return values and internal error messages. ═══ 7.1. Return Values and Functions ═══ The following is a list of possible return values and associated function names: o BOF Rexxbase_ReadDBF Rexxbase_ReadDBF Rexxbase_ReadDBF Rexxbase_GoToRecord Rexxbase_GoToRecord Rexxbase_ScanForRecord Rexxbase_ScanForRecord o Bad Record Number Rexxbase_GoToRecord o Bad Variable Name. Rexx Rtn is %2.2x\0 Rexxbase_OpenDBF o Bad Variable Name; rc is %2.2x\0 Rexxbase_CreateDBF Rexxbase_CreateFromDBF o Can't Create Area For Join Rexxbase_JoinDBF o Can't Find filename Rexxbase_SortDBF o Can't Open Index File, Database Is Open Rexxbase_OpenDBF o Can't Open Sort DBF File Rexxbase_SummarizeDBF Rexxbase_SortDBF o Can't Open filename Rexxbase_OpenDBF o Can't Write To Sort DBF file Rexxbase_SummarizeDBF Rexxbase_SortDBF o Create Failed Rexxbase_CreateDBF o Create Index File Failed Rexxbase_CreateMultipleIndexFile o CreateFrom Failed Rexxbase_CreateFromDBF o Database Name Already In Use Rexxbase_OpenDBF Rexxbase_CreateDBF Rexxbase_CreateFromDBF o Database Tied TO A Join Rexxbase_ReindexDBF o Database Tied To A Join Rexxbase_CloseDBF Rexxbase_ReadDBF Rexxbase_ReadPrevDBF Rexxbase_GoToRecord Rexxbase_WriteDBF Rexxbase_UpdateDBF Rexxbase_ScanForRecord Rexxbase_CreateFromDBF Rexxbase_ModifyDBF Rexxbase_DeleteRecord Rexxbase_UndeleteRecord Rexxbase_FindRecord Rexxbase_ChangePrimaryIndex Rexxbase_CreateIndex Rexxbase_CreateMultipleIndexFile Rexxbase_AddTagToIndex Rexxbase_DropTagFromIndex Rexxbase_PackDBF Rexxbase_SummarizeDBF Rexxbase_SortDBF o Failed To Add Tag To Index Rexxbase_AddTagToIndex o Failed To Drop Tag From Index Rexxbase_DropTagFromIndex o First Database Name Unknown Rexxbase_JoinDBF o First Joined DBF Name Not Specified Rexxbase_JoinDBF o Index File Not Opened Rexxbase_ChangePrimaryIndex o Index File Not Opened or Tag Set Rexxbase_FindRecord o Index Limit Reached Rexxbase_OpenDBF o Index Not Built Rexxbase_CreateIndex o Index Tag Name Not Found Rexxbase_SetIndexTagName o Internal File Processing Error Rexxbase_ReadDBF Rexxbase_ReadPrevDBF Rexxbase_GoToRecord Rexxbase_ScanForRecord Rexxbase_FindRecord Rexxbase_SummarizeDBF Rexxbase_SortDBF o Internal processing error Rexxbase_JoinDBF o Invalid Condition Found Rexxbase_FilterDBF Rexxbase_ScanForRecord Rexxbase_JoinDBF o Invalid Field Specification Found Rexxbase_JoinDBF o Invalid Index Ordinal Rexxbase_ChangePrimaryIndex Rexxbase_ChangePrimaryIndex o Invalid Record Position Rexxbase_UpdateDBF o Join Database Name Already In Use Rexxbase_JoinDBF o Missing Index File Name, Database is open. Rexxbase_OpenDBF o Modify Failed Rexxbase_ModifyDBF o New Tag Name Too Long Rexxbase_AddTagToIndex o No Conditions Specified Rexxbase_ScanForRecord o No DBF Name To Copy Structure To Rexxbase_CreateFromDBF o No Filename Assigned To Variable Rexxbase_CreateDBF o No Filename Assigned To Variable Rexxbase_OpenDBF Rexxbase_CreateFromDBF o No Index Field Names Specified Rexxbase_CreateIndex o No Index File Name Specified Rexxbase_CreateIndex Rexxbase_CreateMultipleIndexFile o No Index Ordinal Specified Rexxbase_ChangePrimaryIndex o No Index Tag File Opened Rexxbase_SetIndexTagName o No Index Tag Name Specified Rexxbase_SetIndexTagName o No Joining Condition Specified Rexxbase_JoinDBF o No Joining Fields Specified Rexxbase_JoinDBF o No Locate String Specified Rexxbase_FindRecord o No New Tag Name Specified Rexxbase_AddTagToIndex Rexxbase_DropTagFromIndex o No Record Number Specified Rexxbase_GoToRecord o No Record Read Rexxbase_DeleteRecord Rexxbase_UndeleteRecord o No Rexx DBF Name Specified Rexxbase_OpenDBF Rexxbase_CloseDBF Rexxbase_ReadDBF Rexxbase_ReadPrevDBF Rexxbase_GoToRecord Rexxbase_WriteDBF Rexxbase_UpdateDBF Rexxbase_FilterDBF Rexxbase_ScanForRecord Rexxbase_CreateDBF Rexxbase_CreateFromDBF Rexxbase_ModifyDBF Rexxbase_DeleteRecord Rexxbase_UndeleteRecord Rexxbase_FindRecord Rexxbase_SetIndexTagName Rexxbase_ChangePrimaryIndex Rexxbase_CreateIndex Rexxbase_CreateMultipleIndexFile Rexxbase_AddTagToIndex Rexxbase_DropTagFromIndex Rexxbase_ReindexDBF Rexxbase_PackDBF Rexxbase_SummarizeDBF Rexxbase_SortDBF o No Rexx Joined DBF Name Specified Rexxbase_JoinDBF o No Sort DBF Name Specified Rexxbase_SummarizeDBF Rexxbase_SortDBF o No Tag Index Fields Specified Rexxbase_AddTagToIndex Rexxbase_DropTagFromIndex o Not Enough Memory For Sorting Rexxbase_SummarizeDBF Rexxbase_SortDBF o Not Enough Memory For Summarizing or Sorting Rexxbase_SummarizeDBF o Primary Index File Not MDX Format Rexxbase_DropTagFromIndex o Primary Index Not MDX Type Rexxbase_SetIndexTagName o Record Locked Rexxbase_SortDBF o Record Not Found Rexxbase_FindRecord Rexxbase_FindRecord Rexxbase_FindRecord Rexxbase_FindRecord Rexxbase_FindRecord o Record locked Rexxbase_ReadDBF Rexxbase_ReadPrevDBF Rexxbase_GoToRecord Rexxbase_ScanForRecord Rexxbase_FindRecord Rexxbase_JoinDBF Rexxbase_SummarizeDBF o Record with duplicate key not updated Rexxbase_UpdateDBF Rexxbase_PackDBF o Record with duplicate key not written Rexxbase_WriteDBF o Second Database Name Unknown Rexxbase_JoinDBF o Second Joined DBF Name Not Specified Rexxbase_JoinDBF o Sort Field Count Not Found Rexxbase_SummarizeDBF Rexxbase_SortDBF o TOF Rexxbase_ReadPrevDBF Rexxbase_ReadPrevDBF Rexxbase_GoToRecord o Tag Index File Has No Tags Rexxbase_SetIndexTagName o Tag Index File Not Opened Rexxbase_AddTagToIndex Rexxbase_DropTagFromIndex o Unable To Write Fields To File; rc = %3.3d Rexxbase_SummarizeDBF Rexxbase_SortDBF o Unknown Database Name Rexxbase_CloseDBF Rexxbase_ReadDBF Rexxbase_ReadPrevDBF Rexxbase_GoToRecord Rexxbase_WriteDBF Rexxbase_UpdateDBF Rexxbase_FilterDBF Rexxbase_ScanForRecord Rexxbase_CreateFromDBF Rexxbase_ModifyDBF Rexxbase_DeleteRecord Rexxbase_UndeleteRecord Rexxbase_FindRecord Rexxbase_SetIndexTagName Rexxbase_ChangePrimaryIndex Rexxbase_CreateIndex Rexxbase_CreateMultipleIndexFile Rexxbase_AddTagToIndex Rexxbase_DropTagFromIndex Rexxbase_ReindexDBF Rexxbase_PackDBF Rexxbase_SummarizeDBF Rexxbase_SortDBF ═══ 7.2. Internal Errors. ═══ The following is a list of internal errors. o All other data ignored after DBF name o All other data ignored after Sort DBF name o Bad date found, changed to all spaces. o Bad field type when getting field value o Bad_Field_Count o Can not find tagname o Can't allocate memo space o Can't make float field part of a key o Can't make logical field part of a key o Can't make memo field part of a key o Can't rebuild, new file not created o Can't rebuild, old file not open o Can't rename file for modify o Data Type Mismatch o Duplicate key not written to index file o Error while reading record, packing continues o Field Length Not Defined o Field Length Not Defined Correctly o Field Name Not Okay o Field Not Defined o Field Size Not Defined Correctly o Field Type Not Defined o Field Type Not Valid o Field delimiter character not found. Import stops. o Field truncated o Field truncated. o Field_Not_Defined o Invalid expression o Invalid expression - data type mismatch o Invalid expression - invalid logic connector o Key length too long o Key length too short o MDX File Already Opened o Memo field missing field delimiter, Import stops. o Memo field missing start field delimiter, Import stops. o Memo fields not allowed in conditions o No records to index o Not enough memory for index sorting o Not enough memory for mdx sorting o Numeric field expected, not found on input file. Import stops. o Read record size does not match o Record Size Too Large o Record with duplicate key not written o Tag name already in use. o Third parameter must be EXACT. Parameter ignored o Too many files opened o Unable to change memo file size. o Unexpected encounter in read text file o Unknown delimiter character found. Import stops o Unknown field name in field list o Unknown field specified in key file define o Unknown field specified in key file open o Unknown name in expression o Unknown operator type in parse expression logic o Would add duplicate o Written record size does not match o alloc error o invalid expression - data type mismatch o logic field value invalid, value set to 'F' o memo field write failed o memo update failed o passed bad memopointer to write memo ═══ 8. Control Variables. ═══ The following is a description of RexxBase error, file, and date handling and extended control facilities. ═══ 8.1. RexxBase Errors ═══ Errors are reported in two different ways, return codes and the error stem variable. If the RexxBase function returns a value other than "" then the function did not complete successfully. ═══ 8.1.1. Where To Find Internal Error Messages ═══ You may direct error message to one of three targets. ┌──────────┬─────────────────────────────────────────────┐ │Target │Description │ ├──────────┼─────────────────────────────────────────────┤ │CON │RexxBase sends all error messages to the │ │ │STDIO file, or console. This is the default.│ ├──────────┼─────────────────────────────────────────────┤ │PRN │RexxBase sends all error messages to the PRN │ │ │file, or printer. │ ├──────────┼─────────────────────────────────────────────┤ │STEM │All messages, for the last executed RexxBase │ │ │function are sent to the stem variable │ │ │RexxBase.Error. See below. │ └──────────┴─────────────────────────────────────────────┘ You should set this variable prior to initializing RexxBase. /* */ RexxBase.Error = 'stem' /* sends rexxbase errors to the stem variable */ ... dbf = '' rc = RexxBase_OpenDBF('dbf') if rc <> '' then do do i = 1 to rexxbase.error.0 say rexxbase.error.i end end ... Whether a function failed or not, there maybe other types of errors and warning messages that are useful to your program. These messages are found in the RexxBase error stem variable. All internal system and control errors can be directed to a stem variable named REXXBASE.ERROR. The zeroth element is a counter This element contains them number of errors in the stem variable. Each time you call a RexxBase function the counter is reset to zero. Your procedure should check what is returned from the function call. For a further description of stem variables refer to your Rexx documentation. ═══ 8.1.2. Internal Error List. ═══ The following is a list of errors and a brief explanation. Error Description All other data ignored after Sort DBF name More parameters were specified than are required Logic field value invalid, value set to 'F' The value of a logic field, which will be adding to or updating a database record contained an invalid value. Can't position at end of memo file There is a severe error with a DBT file. Bad field type when getting field value Internal error - A field type has changed Bad date found, changed to all spaces. The value of a date field, which will be added to or updating a database record contained an invalid value. All other data ignored after DBF name More parameters were specified than are required Dos open error ### for file @@@@@@@@@@ Operating system error, value found in ###, while trying to open file @@@@@@@@@@@ Dos read anchor error #### for file @@@@@@@@@@ Operating system error, value found in ###, while trying to read file @@@@@@@@@@@ Unknown field specified in key file open A field name specified in an index build is not part of the database Can't make memo field part of a key A field name specified in an index build is a memo field. Memo fields can not be part of an index. Can't make logical field part of a key A field name specified in an index build is a logical field. Logical fields can not be part of an index. Unknown field specified in key file define A field name specified in an index build is not in the database. Key length too short Internal error, the calculated length for a key is less than one (1). Would add duplicate Writing a new record to database creates a duplicate key. Unique key value is FALSE. Dos write anchor error #### for file @@@@@@@@@@ Operating system error, value found in ###, while trying to write file @@@@@@@@@@@ Not enough memory for index sorting. Not enough internal memory space to create temporary sort file for indexing function. Can't rename file for modify Modify Structure function attempts to rename the old file. Failure probably caused by duplicate name. Can't rebuild, old file not open Internal error. Somehow the file has been closed. Can't rebuild, new file not created Modify Structure function attempted to create the new file. Old file has been renamed but ...failure probably caused by duplicate name or lack of disk space. Unable to allocate temp file memory ## Not enough internal memory space to create file space. Operating system error value is ## Dos open error ### for text file @@@@@@@@@@@ Operating system error, value found in ###, while trying to open DBT file @@@@@@@@@@@ Field Not Defined Create function error - can not find variable. Bad Field Count Field count for Create is either less than 1 or greater than 128 Field Name Not Okay Field name does not satisfy naming convention. Field Type Not Defined Create function needs to know the field type(characteristics) Field Type Not Valid Field type specified is not C, D, L, N or M. Field Type Not Valid Create function needs to know the field length Field Length Not Defined Correctly The field length requested does not satisfy the length limitations for its type. Record Size Too Large Calculated record length is greater than 4000. 4000 is maximum allowed. ═══ 8.2. File Control Variables ═══ RexxBase offers several control variables to enhance control over your database files. ═══ 8.2.1. REXXBASE.UPDATEHEADERCOUNTER. ═══ You can control how often the database header record gets updated. You change the RexxBase.UpdateHeaderCounter. This sets an internal counter indicating how often after every RexxBase_WriteDBF command the header record is updated. The higher the number the less often the header record is updated. But if the header record is not updated and there is a system crash then the header record will not contain accurate information. The default value is one. A value of zero indicates that the header record is only updated when the database is closed. The value is only set when a database is opened. Therefore changing the value after a database has been opened has no affect on that database. ═══ 8.2.2. Safety - Preventing File Deletion ═══ REXXBASE.SAFETY allows for a level of protection from destroying, deleting or overwriting database and index files. When your routine sets REXXBASE.SAFETY to "ON", anytime RexxBase opens a file, in a creation function (i.e. sort output file, create index, etc.) the function will fail. Check both the return code from the function and/or the rexxbase.error stem variable. When REXXBASE.SAFETY is set to "OFF" then any routine can destroy a file. There may be information in the rexxbase.error stem variable but the return code, even if successful, will be "". The default value is "OFF". If set incorrectly the default value will be used. ═══ 8.2.3. REXXBASE.READ ═══ When REXXBASE.READ is set to "OFF" then the Rexxbase_OpenDBF will open the file for NO read access. This means any routine that reads a file, that was opened when set REXXBASE.READ was set to "OFF", will fail. The default value is "ON". If set incorrectly the default value will be used. ═══ 8.2.4. REXXBASE.WRITE ═══ When REXXBASE.WRITE is set to "OFF" then the Rexxbase_OpenDBF will open the file for NO write access. This means any routine that writes to a file, that was opened when set REXXBASE.READ was set to "OFF", will fail. The default value is "ON". If set incorrectly the default value will be used. ═══ 8.2.5. REXXBASE.UNIQUE ═══ When REXXBASE.UNIQUE is set to "ON" then the Rexxbase_CreateIndex creates an index file with unique keys. This prevents duplicate keys from being added to the index file. When REXXBASE.UNIQUE is set to "OFF" then the Rexxbase_CreateIndex creates an index file without unique keys. This allows duplicate keys from being added to the index file with Rexxbase_ReadDBF and Rexxbase_UpdateDBF functions. The default value is "OFF". If set incorrectly the default value will be used. This control is less restrictive than Rexxbase.ALLOWDUPLICATEINDEXES. ═══ 8.2.6. REXXBASE.ALLOWDUPLICATEINDEXES ═══ When REXXBASE.ALLOWDUPLICATEINDEXES is set to "NO" the RexxBase_WriteDBF and RexxBase_UpdateDBF functions will not add record when another record with a similar index is present. This control is more restrictive than Rexxbase.UNIQUE. When REXXBASE.ALLOWDUPLICATEINDEXES is set to "YES" then the Rexxbase_WriteDBF and Rexxbase_UpdateDBF can add records to the DBF even if a duplicate key exists. The default value is "YES". If set incorrectly the default value will be used. ═══ 8.2.7. REXXBASE.SHARE ═══ Rexxbase offers a facility for file sharing your databases. When REXXBASE.SHARE is set to "OFF" then the Rexxbase_OpenDBF will open the file NO OTHER external program file access. This will prevent any other program in the system from accessing the file. Also, if the file is already opened, by another program, your routine will fail. This is file locking. When REXXBASE.SHARE is set to "READ" then the Rexxbase_OpenDBF will open the file for read only sharing. This will allow any other program in the system to read your open database file. Also, if the file is already opened by another program for no read sharing, your routine will fail. When REXXBASE.SHARE is set to "WRITE" then the Rexxbase_OpenDBF will open the file for write only sharing. This will allow any other program in the system to have write access the file, not read access. Also, if the file is already opened by another program for no write sharing, your routine will fail. When REXXBASE.SHARE is set to "READWRITE" then the Rexxbase_OpenDBF will open the file for read and write sharing. This will allow any other program in the system to have access the file. Also, if the file is already opened by another program for no sharing, your routine will fail. The default value is "OFF". If set incorrectly the default value will be used. You may set REXXBASE.SHARE at anytime and as often as you like. But it is only used when the database is opened with a Rexxbase_OpenDBF. ═══ 8.3. Controlling Date Format. ═══ RexxBase offers a way to control the format of dates. By turning the format control on and off dates are presented in either internal xBase format or in a display format. ═══ 8.3.1. REXXBASE.INCLUDECENTURY ═══ When RexxBase.IncludeCenture is turned "ON" then all date fields are required to specify dates with the century. Format is CCYYMMDD. This parameters enforces a requirement that when a date is passed to REXXBASE the century value is included. If century is not included RexxBase will replace the date string with spaces. If RexxBase.IncludeCentury is set to 'OFF' (the default value) a value of current century is preappended to the year. The default value may create incorrect internal date values. Your system is better of if your programs supply the century. Thereby requiring you to consistently use the correct value. ═══ 8.3.2. REXXBASE.FORMATDATE. ═══ When RexxBase.FormatDate is turned "OFF" then all date fields are in the following 8 numeric-character format: CCYYMMDD. CC - century. YY - year. MM - month. DD - day. If RexxBase.FormatDate is "ON", the default value, then date fields are formatted based on the Country Code. as follows: (all are 8 bytes long with separators). MM/DD/YY, slashes or some other separator is required DD/MM/YY, slashes or some other separator is required YY/MM/DD, slashes or some other separator is required The default value is "ON". If set incorrectly the default value will be used. ═══ 8.4. Controlling File Format. ═══ RexxBase offers a way to control which file format version of dBase to use. By specifying the format you are able to use either dBase III or dBase IV formats. dBase internal file structure allows for files to be identified with one exception. If a database does not use a memo field and a dBase IV file does not use a float field then there is not way to distinguish between the two versions. Therefore, you should always specify the file format. ═══ 8.4.1. REXXBASE.dBaseFileFormat. ═══ When RexxBase.dBaseFileFormat is set to "dBase3", the default value, then all database functions are processed in dBase III format. When set to "dBase4", the files are processed using dBase IV format. If set incorrectly the default value will be used. ═══ 8.4.2. REXXBASE.REXXLOGICAL ═══ When RexxBase.REXXLOGICAL is set to 'ON', logical fields internally set to 'Y' will be set externally to '1' and fields set to 'N" will be set as '0', When set to 'OFF', the internal value of a logical field is set. If set incorrectly the default value "OFF" will be used. ═══ 8.4.3. REXXBASE.SKIPDELETED ═══ When RexxBase.SKIPDELETED is set to 'ON' then all RexxBase functions used to retrieve records will not return a deleted record. This will cause either the next non-deleted record to be returned or a NOT FOUND condition to occur. When set to 'OFF', the default value, deleted records are returned. If set incorrectly the default value will be used. ═══ 8.5. Binary Data Control. ═══ RexxBase offers a way to store binary data in CHAR and MEMO fields. While storing binary data is not in itself tricky, previous versions of RexxBase used null terminated strings to determine data size and length. dBase III DBT files store memo fields with two (2) end of file indicators hex(1a). Therefore if your binary data contains this character then the field will be terminated prematurely. To avoid this situation, use the dBase IV format. ═══ 8.5.1. REXXBASE.UseStringLengths. ═══ When RexxBase.UseStringLengths is set to "YES", the default value, then all CHAR and MEMO fields will be stored and retrieved with lengths based on a null terminating character in the data field. When set to "NO", the fields are stored and returned to you using the specific length as either measured by REXX or stored in the DBT file. If set incorrectly the default value will be used. ═══ 9. Next Releases. ═══ The following is a list of the next planned releases. ═══ 9.1. Multi-User Access. ═══ While file locking is fine for some applications a true multi-user control is need for a LAN system. ═══ 10. Suggestions and Bugs. ═══ Please call or write to us at our address with suggestions or to report bugs. You can reach us through E-Mail by contacting Joe McVerry at joe@usacoder.rtp.nc.us ═══ 11. Shareware Software ═══ DEFINITION OF SHAREWARE SOFTWARE Shareware Software distribution gives users a chance to try software before buying it. If you try a Shareware software program and continue using it, you are expected to register. Individual programs differ on details -- some request registration while others require it, some specify a maximum trial period. With registration, you get anything from the simple right to continue using the software to an updated program with printed manual. ═══ 11.1. Copyright ═══ Copyright laws apply to both Shareware and commercial software, and the copyright holder retains all rights, with a few specific exceptions as stated below. Shareware software authors are accomplished programmers, just like commercial authors, and the programs are of comparable quality. (In both cases, there are good programs and bad ones!) The main difference is in the method of distribution. The author specifically grants the right to copy and distribute the software, either to all and sundry or to a specific group. For example, some authors require written permission before a commercial disk vendor may copy their Shareware software. ═══ 11.2. Distribution. ═══ Shareware software is a distribution method, not a type of software. You should find software that suits your needs and pocketbook, whether it's commercial or Shareware software. The Shareware software system makes fitting your needs easier, because you can try before you buy. And because the overhead is low, prices are low also. Shareware software has the ultimate money-back guarantee -- if you don't use the product, you don't pay for it. ═══ 12. Disclaimer ═══ DISCLAIMER - AGREEMENT Users of RexxBase must accept this disclaimer of warranty: "REXXBASE IS SUPPLIED AS IS. AMERICAN CODERS DISCLAIMS ALL WARRANTIES, EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, THE WARRANTIES OF MERCHANTABILITY AND OF FITNESS FOR ANY PURPOSE. AMERICAN CODERS LTD. ASSUMES NO LIABILITY FOR DAMAGES, DIRECT OR CONSEQUENTIAL, WHICH MAY RESULT FROM THE USE OF REXXBASE." ═══ 13. Sharing RexxBase ═══ RexxBase is a "Shareware software program" and is provided at no charge to the user for evaluation. Feel free to share it with your friends, but please do not give it away altered or as part of another system. The essence of "user-supported" software is to provide personal computer users with quality software without high prices, and yet to provide incentive for programmers to continue to develop new products. If you find this program useful and find that you are using RexxBase and continue to use RexxBase after a reasonable trial period of 30 days, you must make a registration payment of $95.00 to American Coders, Ltd. The $95.00 registration fee will license one copy for use on any one computer at any one time. You must treat this software just like a book. An example is that this software may be used by any number of people and may be freely moved from one computer location to another, so long as there is no possibility of it being used at one location while it's being used at another. Just as a book cannot be read by two different persons at the same time. ═══ 13.1. Commercial Users ═══ Commercial users of RexxBase must register and pay for their copies of RexxBase within 30 days of first use or their license is withdrawn. Site-License arrangements may be made by contacting American Coders, Ltd. ═══ 13.2. Distributing ═══ Anyone distributing RexxBase for any kind of remuneration must first contact American Coders, Ltd. at our address below for authorization. This authorization will be automatically granted to distributors recognized by the (ASP) as adhering to its guidelines for shareware distributors, and such distributors may begin offering RexxBase immediately (However American Coders, Ltd. must still be advised so that the distributor can be kept up-to-date with the latest version of RexxBase.). ═══ 13.3. Pass Along ═══ You are encouraged to pass a copy of RexxBase along to your friends for evaluation. Please encourage them to register their copy if they find that they can use it. All registered users will receive a copy of the latest version of the RexxBase system.